package com.woniu.config;

import com.google.common.base.Charsets;
import com.google.common.hash.Funnel;
import com.woniu.filter.BloomFilterHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.Arrays;

/**
 * 基于redis 配置布隆过滤器
 *
 * @author zrh
 */
@Configuration
public class BloomRedisConfig {

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 初始化布隆过滤器实例
     */
    private static final BloomFilterHelper bloomFilterHelper = new BloomFilterHelper(10000000L, 0.01,
            (Funnel<String>) (from, into) -> into.putString(from, Charsets.UTF_8));

    /**
     * 添加初始数据到布隆过滤器
     *
     * @param key
     * @param value
     * @param <T>
     */
    public <T> void addByBloomFilter(String key, T value) {
        // 根据随机hash函数计算元素hash值
        Long[] mightContain = bloomFilterHelper.mightContain(value);
        // 对redis里的比特位进行赋值
        Arrays.stream(mightContain).forEach(o -> redisTemplate.opsForValue().setBit(key + value, o, true));
    }

    /**
     * 验证数据是否存在
     *
     * @param key
     * @param value
     * @param <T>
     * @return
     */
    public <T> Boolean includeByBloomFilter(String key, T value) {
        // 根据随机hash函数计算元素hash值
        Long[] mightContain = bloomFilterHelper.mightContain(value);
        // 判断是否
        return !Arrays.stream(mightContain).anyMatch(o -> !redisTemplate.opsForValue().getBit(key + value, o));
    }
}
